package com.test.jdk.funtionRel;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.Date;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

/**
 * 测试方法引用：
 * 方法引用的使用：
 * 1. instanceName::methodName 对象::方法名
 * 2. ClassName::staticMethodName 类名::静态方法
 * 3. ClassName::methodName 类名::普通方法
 * 4. ClassName::new 类名::new 调用的构造器
 * 5. TypeName[]::new String[]::new 调用数组的构造器
 */
public class FunctionRefTest01 {
    public static void main(String[] args) {

        //lambda 表达式的写法
        printMax(a -> {
            int sum = 0;
            for (int i : a) {
                sum += i;
            }
            System.out.println("数组的求和为：" + sum);
        });

        //直接方法引用 :: 引用的方法类型与与lambda表达式中实现一致，方法的类型与函数式接口的类型一致
        //作用效果与lambda表达式一样
        // 自定义方法引用
        printMax(FunctionRefTest01::getTotal);
        //方法引用：1. instanceName::methodName 对象::方法名
        //lombad表达式写法
        Date now = new Date();
        //lombda表达式写法
        Supplier<Long> longSupplier = () -> {
            return now.getTime();
        };
        System.out.println(longSupplier.get());
        //方法引用进行替换
        Supplier<Long> supplier = now::getTime;
        System.out.println(now.getTime());

        //方法引用的使用二：类名::静态方法名
        Supplier<Long> supplier1 = () -> {
            return System.currentTimeMillis();
        };
        System.out.println(supplier1.get());
        //方法引用替代System::currentTimeMillis
        Supplier<Long> supplier2 = System::currentTimeMillis;
        System.out.println(supplier2.get());

        //方法引用三： 类名::引用实例方法
        Function<String, Integer> integerFunction = (s) -> {
            return s.length();
        };
        System.out.println(integerFunction.apply("hhhhhhh"));
        //方法引用进行替代
        Function<String, Integer> integerFunction1 = String::length;
        System.out.println(integerFunction1.apply("hhhhhhh"));

        //三参函数式接口 lambda表达式写法
        BiFunction<String, Integer, String> biFunction1 = (msg, index) -> {
            return msg.substring(index);
        };
        //对msg 字符进行截取
        System.out.println("wwwwwwheshsnsdsds".length());
        System.out.println(biFunction1.apply("wwwwwwheshsnsdsds", 5));

        //方法引用进行替代
        BiFunction<String, Integer, String> biFunction = String::substring;
        System.out.println(biFunction.apply("wwwwwwheshsnsdsds", 5));
        //方法引用四：类名::构造器 构造器的名称和类名完全一致，所以构造器引用使用 ::new 的格式使用
        //lambda表达式写法
        Supplier<Person> personSupplier1=()->{
            return new Person(18,"hehehe");
        };
        System.out.println(personSupplier1.get());//Person{age=18, name='hehehe'}
        //该引用只能设置无参构造器
        Supplier<Person> personSupplier=Person::new;
        System.out.println(personSupplier.get());//Person{age=null, name='null'}

        //两参构造器
        BiFunction<Integer,String,Person> personBiFunction=Person::new;
        Person hehehe = personBiFunction.apply(18, "hehehe");
        System.out.println(hehehe);


        //方法引用五：数组::构造器
        //lambda表达式写法
        Function<Integer,String[]> integerFunction2=(len)->{
            return new String[len];
        };
        String[] apply = integerFunction2.apply(5);
        System.out.println("数组的长度是："+apply.length);
        //方法引用
        Function<Integer,String[]> integerFunction3=String[]::new;
        String[] apply1 = integerFunction3.apply(5);
        System.out.println("数组的长度是："+apply1.length);


    }

    /**
     * 定义一个求和的方法
     */
    private static void getTotal(int[] array) {
        int sum = 0;
        for (int i : array) {
            sum += i;
        }
        System.out.println("数组的求和为：" + sum);
    }

    private static void printMax(Consumer<int[]> consumer) {
        int[] a = {10, 20, 30, 40, 50, 60};
        consumer.accept(a);
    }
}
